package android_testsuite.mytest.network_test;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.nio.charset.Charset;

import android_testsuite.mytest.util.Const;


public class TcpServer {
    private int mPort;
    private Selector mSelector;

    public TcpServer() {
        mPort = Const.PORT;
    }

    public TcpServer(int port) {
        mPort = port;
    }

    //处理连接请求
    public void acceptAction(SelectionKey key) {
        ServerSocketChannel ssc = (ServerSocketChannel) key.channel();
        try {
            SocketChannel sc = ssc.accept();
            if (sc == null) {
                return ;
            }
            sc.configureBlocking(false);
            sc.register(mSelector,SelectionKey.OP_READ);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    //处理读请求
    public void readAction(SelectionKey key) {
        ByteBuffer buffer = ByteBuffer.allocate(Const.BUFFER_SIZE);
        SocketChannel sc = (SocketChannel) key.channel();
        int readBytes = 0;
        String message = null;
        try {
            int ret;
            try {
                while ((ret = sc.read(buffer)) > 0) {
                    readBytes += ret;
                }
            } catch (Exception e) {
                readBytes = 0;
            } finally {
                buffer.flip();
            }

            if (readBytes > 0) {
                message = Charset.forName("UTF-8").decode(buffer).toString();
                buffer = null;
            }
        } finally {
            if (buffer != null) {
                buffer.clear();
            }
        }

        if (readBytes > 0) {
            System.out.println("message from client:" + message);
            try {
                if ("quit".equalsIgnoreCase(message.trim())) {
                    sc.close();
                    mSelector.close();
                    System.out.println("Server has been shutdown");
                    System.exit(0);
                }

                String outMessage = "server response:" + message;
                sc.write(Charset.forName("UTF-8").encode(outMessage));
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }


    public void run() throws IOException {
        //打开选择器
        mSelector = Selector.open();
        //打开服务器通道
        ServerSocketChannel ssc = ServerSocketChannel.open();
        //获得套接字
        ServerSocket serverSocket = ssc.socket();
        //绑定端口
        serverSocket.bind(new InetSocketAddress(mPort));
        System.out.println("server listen on port :" + mPort);
        //设置为非阻塞模式
        ssc.configureBlocking(false);
        //给选择器注册操作事件
        ssc.register(mSelector, SelectionKey.OP_ACCEPT);

        while (true) {
            int nKeys = mSelector.select(1000);
            if (nKeys > 0) {
                for (SelectionKey key : mSelector.selectedKeys()) {
                    if (key.isAcceptable()) {
                        acceptAction(key);
                    } else if (key.isReadable()) {
                        readAction(key);
                    }
                }
                mSelector.selectedKeys().clear();
            }
        }
    }
}
